//
//  set_demo.cpp
//  cpp_learn
//
//  Created by 李贺 on 2021/12/30.
//

#include "set_demo.hpp"

namespace set_test_demo {

bool fncomp (int lhs, int rhs) {return lhs<rhs;}

struct classcomp {
  bool operator() (const int& lhs, const int& rhs) const
  {return lhs<rhs;}
};

using FnFunc = bool (*)(int,int);

void test_init() {
    set<int> first;
    
    int myints[] = {10,20,30,40};
    set<int> second(myints,myints+2);
    
    set<int> third(second);
    set<int> forth(third.begin(),third.end());
    set<int, classcomp> fifth;
    
    FnFunc fn_pt = fncomp;
    set<int, bool(*)(int,int)> sxt(fn_pt);
}

void test_op() {
    set<int> first;
    
    int myarr[5] = {5};
    set<int> second(myarr, myarr+5);
    
    first = second;
    second = set<int>();
}

void test_size() {
    set<int> first;
    cout << first.empty() << endl;
    first.insert(1);
    first.insert(2);
    first.insert(3);
    first.insert(4);
    cout << first.empty() << endl;
    cout << first.size() << endl;
    cout << first.max_size() << endl;
}

void test_insert() {
    set<int> ss;
    
    set<int>::iterator it;
    pair<set<int>::iterator, bool> ret;
    
    for (int i = 1; i < 5; ++i) {
        ss.insert(i*10);
    }
    
    ret = ss.insert(20);
    if (ret.second == false) {
        it = ret.first;
    }
    
    
    ss.insert (it,25);                 // max efficiency inserting
    ss.insert (it,24);                 // max efficiency inserting
    ss.insert (it,26);                 // no max efficiency inserting
    
    int myintsp[] = {5,10,15};
    ss.insert(myintsp, myintsp+3);
    
    std::cout << "myset contains:";
    for (it = ss.begin(); it != ss.end(); ++it) {
        std::cout << ' ' << *it;
    }
    std::cout << '\n';
}

void test_erase() {
    std::set<int> myset;
    std::set<int>::iterator it;
    
    for (int i=1; i<10; i++) {
        myset.insert(i*10);
    }
    
    it = myset.begin();
    ++it;
    
    myset.erase(it);
    myset.erase(40);
    
    it = myset.find(60);
    myset.erase(it, myset.end());
    
    std::cout << "myset contains:";
    for (it=myset.begin(); it!=myset.end(); ++it) {
        std::cout << ' ' << *it;
    }

    std::cout << '\n';
}

void test_swap() {
    set<int> first;
    first.insert(10);
    
    set<int> second;
    second.insert(20);
    
    first.swap(second);
}

void test_clear() {
    std::set<int> myset;
    
    for (int i=1; i<10; i++) {
        myset.insert(i*10);
    }
    
    cout << "set value";
    for (auto it = myset.begin(); it != myset.end(); ++it) {
        cout << ' ' << *it;
    }
    cout << endl;
    
    myset.clear();
    cout << "set value";
    for (auto it = myset.begin(); it != myset.end(); ++it) {
        cout << ' ' << *it;
    }
    cout << endl;
}

void test_lower_bound() {
    set<int> myset;
    set<int>::iterator itlow,itup;
    for (int i=1; i<10; i++) {
        myset.insert(i*10); // 10 20 30 40 50 60 70 80 90
    }
    
    itlow = myset.lower_bound(30);
    itup = myset.upper_bound(60);
    
    myset.erase(itlow, itup);
    
    std::cout << "myset contains:";
    for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it) {
        std::cout << ' ' << *it;
    }
    std::cout << '\n';

}

void test_key_compare() {
    std::set<int> myset;
    int highest;
    // key_compare 的表达式相当于 <
    std::set<int>::key_compare mycomp = myset.key_comp();

    for (int i=0; i<=5; i++) myset.insert(i);

    std::cout << "myset contains:";
    
    highest = *myset.rbegin();
    std::set<int>::iterator it=myset.begin();
    do {
        std::cout << ' ' << *it;
    } while ( mycomp(*(++it),highest) );

    std::cout << '\n';


}

}
